package com.protocolmeter.frame;

import com.protocolmeter.function.FrameFunction;

/**
 * @ClassName: Frame645
 * @Description: 基本的645规约结构
 * @author baozhijian
 * @date 2017年8月7日 下午8:22:35
 * @version V1.0
 */
public class Meter645 implements Meter {

	private String address;
	private String control;
	private String len;
	private String identification;
	private String psw;
	private String ope;
	private String data;
	private String cs;

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getControl() {
		return control;
	}

	public void setControl(String control) {
		this.control = control;
	}

	public String getLen() {
		return len;
	}

	public void setLen(String len) {
		this.len = len;
	}

	public String getIdentification() {
		return identification;
	}

	public void setIdentification(String identification) {
		this.identification = identification;
	}

	public String getPsw() {
		return psw;
	}

	public void setPsw(String psw) {
		this.psw = psw;
	}

	public String getOpe() {
		return ope;
	}

	public void setOpe(String ope) {
		this.ope = ope;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}

	public String getCs() {
		return cs;
	}

	public void setCs(String cs) {
		this.cs = cs;
	}

	/**
	 * @Title: Meter645.java
	 * @Description: 组帧
	 * @param address
	 * @param control
	 * @param identification
	 * @param psw
	 * @param ope
	 * @param data
	 */
	public Meter645(String address, String control, String identification, String psw, String ope, String data) {
		this.control = control;
		FrameFunction frameFunction = new FrameFunction();
		this.address = address;

		endata(identification, data, psw, ope);

		this.len = Integer.toHexString(
				((this.identification.length() + this.psw.length() + this.ope.length() + this.data.length()) / 2)
						| 0x100)
				.substring(1);

		String temp = "68" + frameFunction.Reverse(this.address) + "68" + this.control + this.len
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.identification, true))
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.psw, true))
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.ope, true))
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.data, true));
		this.cs = frameFunction.Cs(temp);
	}

	private void endata(String identification, String data, String psw, String ope) {
		switch (this.control) {
		case "03":
			this.identification = identification;
			this.data = data;
			this.psw = "";
			this.ope = ope;
			break;
		case "11":// 读数据
			this.identification = identification;
			this.data = "";
			this.psw = "";
			this.ope = "";
			break;
		case "14":// 写数据
			this.identification = identification;
			this.data = data;
			this.psw = psw;
			this.ope = ope;
			break;
		case "13":// 读地址
			this.identification = "";
			this.data = "";
			this.psw = "";
			this.ope = "";
			break;
		case "15":// 写数据
			this.identification = "";
			this.data = data;
			this.psw = "";
			this.ope = "";
			break;
		case "1C":// 跳合闸、报警、保电
			this.identification = "";
			this.data = data;
			this.psw = psw;
			this.ope = ope;
			break;
		default:
			break;
		}
	}

	/**
	 * @Title: BaseFrame.java
	 * @Description: 根据帧，解析645
	 * @param frame
	 */
	public Meter645(String sentdata, String frame) {
		FrameFunction frameFunction = new FrameFunction();
		this.address = frameFunction.Reverse(frame.substring(2, 14));
		this.control = frame.substring(16, 18);
		this.len = frame.substring(18, 20);

		dedata(frame);

		this.cs = frame.substring(frame.length() - 4, frame.length() - 2);
	}

	/**
	 * @Title: Frame645.java
	 * @Description: 解析数据域
	 * @param frame
	 */
	private void dedata(String frame) {
		FrameFunction frameFunction = new FrameFunction();
		switch (this.control) {
		case "91":// 读数据返回
			int i = Integer.valueOf(this.len, 16);
			this.identification = frame.substring(20, 28);
			this.data = frameFunction.Reverse(frameFunction.AddOrSub33(frame.substring(28, 20 + i * 2), false));
			break;
		case "93":// 读地址返回
			this.identification = "";
			this.data = frameFunction.Reverse(frameFunction.AddOrSub33(frame.substring(20, 32), false));
			break;
		case "83":
		case "94":// 写数据返回
		case "95":// 写数据返回
		case "9C":// 跳合闸、报警、保电返回
			this.identification = "";
			this.data = "成功";
			break;
		case "C3":
		case "D1":// 错误
		case "D4":
		case "DC":
			this.identification = "";
			this.data = frameFunction.AddOrSub33(frame.substring(20, 22), false);
			break;
		default:
			break;
		}
	}

	@Override
	public String toString() {
		FrameFunction frameFunction = new FrameFunction();
		return ("68" + frameFunction.Reverse(this.address) + "68" + this.control + this.len
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.identification, true))
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.psw, true))
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.ope, true))
				+ frameFunction.Reverse(frameFunction.AddOrSub33(this.data, true)) + this.cs + "16").toUpperCase();
	}

	@Override
	public String Getdata() {
		return this.identification + "-" + this.data;
	}

}
